package com.weaver;

import org.eclipse.jdt.core.dom.*;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

public class JdtUtil {

    public static boolean scanFile(String fileName) {
        String content = read(fileName);
        //创建解析器
        ASTParser parsert = ASTParser.newParser(AST.JLS2);
        //设定解析器的源代码字符
        parsert.setSource(content.toCharArray());
        //使用解析器进行解析并返回AST上下文结果(CompilationUnit为根节点)
        CompilationUnit result = (CompilationUnit) parsert.createAST(null);

        //获取类型
        List types = result.types();
        //取得类型声明
        TypeDeclaration typeDec = (TypeDeclaration) types.get(0);
        //引用import
        List importList = result.imports();
        //##############获取源代码结构信息#################

        //取得函数(Method)声明列表
        MethodDeclaration methodDec[] = typeDec.getMethods();
        MethodDeclaration method = methodDec[0];
        Block body = method.getBody();
        if (body.toString() == null) {
            return false;
        }
        return checkBody(body,fileName,importList);
    }

    public static boolean checkBody(Block body,String fileName,List importList) {
        String[] methods = {"writeLog", "debugger","debug"};
        String[] fullName = {"System.out.println", "System.out.error"};
        List<ASTNode> statements = body.statements();
        if (statements.size() == 0) {
            return false;
        }
        List<String> ignoreList = new ArrayList<String>();
        List<String> unIgnoreList = new ArrayList<String>();
        for (int i = 0; i < importList.size(); i++) {
            unIgnoreList.add(importList.get(i).toString());
        }
        for (ASTNode astNode : statements) {
            if (astNode instanceof ExpressionStatement) {
                ExpressionStatement statement = (ExpressionStatement) astNode;
                Expression expression = statement.getExpression();

                if (expression instanceof MethodInvocation) {
                    MethodInvocation methodInvocation = (MethodInvocation) expression;
                    String name = methodInvocation.getName().toString();

                    if (Arrays.asList(methods).contains(name)) {
                        ignoreList.add(astNode.toString());
                        continue;
                    }

                    String qualifiledName = methodInvocation.getExpression().toString();
                    if (Arrays.asList(fullName).contains(qualifiledName + "." + name)) {
                        ignoreList.add(astNode.toString());
                        continue;
                    }

                }
            }

            if (astNode instanceof VariableDeclarationStatement) {
                VariableDeclarationStatement statement = (VariableDeclarationStatement) astNode;
                if (statement.getType().toString().equals("BaseBean")) {
                    ignoreList.add(astNode.toString());
                    continue;
                }
            }
            unIgnoreList.add(astNode.toString());
        }

        write(ignoreList, unIgnoreList, fileName);

        if (unIgnoreList.size() == 0) {
            return true;
        }else {
            return false;
        }
    }

    public static void write(List<String> ignoreList,List<String> unIgnoreList,String fileName) {
        String outString = "=========不可以忽略的改变=====" + "\r\n";
        for (int i = 0; i < unIgnoreList.size(); i++) {
            outString += unIgnoreList.get(i) + "\r\n";
        }
        outString += "=========可以忽略的改变=======" + "\r\n";

        for (int i = 0; i < ignoreList.size(); i++) {
            outString += ignoreList.get(i) + "\r\n";
        }
        fileName = fileName.replace(".java", "_result.txt");
        try {
            FileUtil.write(outString, fileName);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    private static String read(String filename){
        File file = new File(filename);
        byte[] b = new byte[(int) file.length()];
        FileInputStream fis = null;
        try {
            fis = new FileInputStream(file);
            fis.read(b);
        } catch (Exception e) {
            e.printStackTrace();
        }finally {
            try {
                fis.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        return new String(b);

    }
}
